<html>
<!-- $LastChangedDate: 2010-02-10 16:36:02 -0500 (Wed, 10 Feb 2010) $ -->
<!-- Copyright (C) 2004,2009 Jim Brooks http://www.palomino3d.org -->
<head>
<title>Palomino - View Module</title>
<link rel='stylesheet' type='text/css' href='docs.css'>
<link rel='icon' type='image/png' href='images/favicon.png'/>
</head>
<body>

<!-- ----------------------------------------------------------------------- -->
<h1>Palomino - View Module</h1>
<p>
&copy;2004,2009&nbsp;&nbsp;Jim E. Brooks
&nbsp;&nbsp;<a href='http://www.palomino3d.org'>http://www.palomino3d.org</a>
</p>
<hr>
<ul>
  <li><a href='index.html'>Index</a></li>
  <li><a href='#Overview'>Overview</a></li>
  <li><a href='#Window'>Window</a></li>
  <li><a href='#View'>View</a></li>
  <li><a href='#Viewpoint'>Viewpoint</a></li>
  <li><a href='#View Matrix'>View Matrix</a></li>
  <li><a href='#Observer'>Observer</a></li>
  <li><a href='#Animating the Viewpoint'>Animating the Viewpoint</a></li>
</ul>

<!-- ----------------------------------------------------------------------- -->
<hr>
<a name='Overview'></a>
<h2>Overview</h2>
<p><!--date-->[2009/10]</p>
<p>
Module to create a window with one or more views.
The purpose of this module is to serve as a layer to allow app-level code
to manipulate views in a way independent of the graphics system.
</p>
<table border='2' cellpadding='4'>
  <tr>
    <td>abstraction:</td>
    <td>Window <img src='images/arrowBlue.gif'></td>
    <td>View <img src='images/arrowBlue.gif'></td>
    <td>Observer Matrix <img src='images/arrowBlue.gif'></td>
    <td>Viewpoint / View Matrix</td>
  </tr>

  <tr>
    <td>implementation:</td>
    <td>osg::Viewer <img src='images/arrowBlue.gif'></td>
    <td>osg::Camera <img src='images/arrowBlue.gif'></td>
    <td></td>
    <td>modelview matrix</td>
  </tr>
</table>
  
<!-- ----------------------------------------------------------------------- -->
<hr>
<a name='Window'></a>
<h2>Window</h2>
<p><!--date-->[2008/06]</p>
<p>
Window class contains Views, defines the <a href='module_graph.html#SceneGraph'>SceneGraph</a>, executes main loop, broadcasts draw events.
Window automatically creates the main view.
Window is based on OSG::Viewer.
</p>

<!-- ----------------------------------------------------------------------- -->
<hr>
<a name='View'></a>
<a name='View and Viewpoint'></a>
<h2>View</h2>
<p><!--date-->[2009/10]</p>
<p>
View defines both a 2D viewport and 3D viewpoint.
The order of rendering Views is the same order Views were attached to Window.
View is based on osg::Camera.
</p>
<p>
Logical views are composed with a View and a <a href='#Viewpoint'>Viewpoint</a> object.
Viewpoint is a functor class containing an algorithm
to compute the <a href='#View Matrix'>View Matrix</a>
which is called before rendering a new frame.
This composition can be changed dynamically by View::SetViewpoint()
to switch to view modes (first-person, chase-plane, etc).
</p>
<p>
The View class is a Mediator over osg::Viewer, osg::View, and osg::Camera.
View::SetViewMatrix() is a pass-thru to osg::Camera::setViewMatrix().
Despite changing the viewpoint, View keeps the same underlying osg::Camera object.
</p>

<!-- ----------------------------------------------------------------------- -->
<hr>
<a name='Viewpoint'></a>
<h2>Viewpoint</h2>
<p><!--date-->[2009/10]</p>
<h3>Viewpoint (design)</h3>
<p>
As described in <a href='#View'>View</a>,
Viewpoint is a functor class whose purpose is to compute
the <a href='#View Matrix'>View Matrix</a> from an
<a href='#Observer'>observer</a>.
</p>
<p>
A <a href='#View'>View</a> has a Viewpoint object.
Every frame, View calls Viewpoint::ComputeViewMatrix() to recompute the viewpoint.
</p>

<!-- ----------------------------------------------------------------------- -->
<hr>
<a name='View Matrix'></a>
<h2>View Matrix</h2>
<p><!--date-->[2009/10]</p>
<p>
View Matrix corresponds to the OpenGL <i>modelview matrix</i>.
It is computed from the <a href='#Observer Matrix'>Observer Matrix</a>
according to view modes.
For example, the View Matrix will be computed appropriately for OTW_FRONT or OTW_LEFT
(the <a href='#Observer Matrix'>Observer Matrix</a> exists independently of view modes).
</p>
<p>
The coordinates of the origin of the View Matrix are negative
<font size='-1'>(osg::Camera's view matrix is also negatve)</font>.
</p>

<!-- ----------------------------------------------------------------------- -->
<hr>
<a name='Observer'></a>
<h2>Observer</h2>
<p><!--date-->[2009/10]</p>
<a name='Observer Matrix'></a>
<h3>Observer and Observer Matrix</h3>
<p>
In general terms, every view of the scene has an object that is the <i>observer</i>.
The observer is an abstraction:
it can be the player's craft, a chase-plane, trackball position, a matrix, etc.
An observer is defined by an <i>Observer Matrix</i>.
The Observer is the source of the <a href='#Viewpoint'>Viewpoint</a> and <a href='#View Matrix'>View Matrix</a>.
An Observer Matrix is converted to a lower-level
<a href='#View Matrix'>View Matrix</a> which is used to render a view.
</p>
<a name='Observer Class'></a>
<h3>Observer Class</h3>
<p>
The generalized Viewpoint class that uses the Observer functor class is OtwViewpoint.
The normal front-view is supported by OTW_FRONT mode.
OtwViewpoint::ComputeViewMatrix() calls Observer::GetObserverMatrix().
New derivatives of Observer can be created to define any kind of observer object.
</p>
<h3>Multiple Observers</h3>
<p>
Multiple Observers can exist.
For example, one View can have the player's craft as an Observer,
while another View has a missile as an Observer.
</p>
<h3>ObserverCurrentCraft</h3>
<p>
The <i>main Observer</i> is ObserverCurrentCraft.
ObserverCurrentCraft drives the main View (depending on program mode).
</p>
<p>
Implementation:
<br>For implementation reasons, multiple instances of ObserverCurrentCraft are possible.
But regardless, ObserverCurrentCraft can be thought of as Singleton in disguise (or a link/proxy),
because it is based on the unique <a href='module_control.html#Current Craft'>current craft</a>.
</p>

<!-- ----------------------------------------------------------------------- -->
<hr>
<a name='Animating the Viewpoint'></a>
<h2>Animating the Viewpoint</h2>
<p><!--date-->[2009/10]</p>
<p>
Movement in the simulator is driven
by a <a href='#Viewpoint'>Viewpoint</a> object recomputing the
<a href='#View Matrix'>View Matrix</a>
of a <a href='#View'>View</a> every frame.
</p>
<p>
Specifically, how does the player cause the viewpoint to move (in an OTW view)?
The main View can be composed with an OtwViewpoint object.
The OtwViewpoint is constructed with a ObserverCurrentCraft object
(derivative of the <a href='#Observer Class'>Observer class</a>).
Every frame, View calls Viewpoint::ComputeViewMatrix(),
which in this case, actually calls OtwViewpoint::ComputeViewMatrix().
In turn, ObserverCurrentCraft::GetObserverMatrix() is called
which gets the Observer Matrix from the <i>current craft</i>
which is what the player controls and is the <i>observer</i>.
Then the <a href='#Observer Matrix'>Observer Matrix</a>
is converted to a <a href='#View Matrix'>View Matrix</a>
according to the OTW mode (front/left/right/rear).
</p>

<!-- ********************************* END ********************************* -->
<hr>
<p align='center'>
<font size='-2'>
<!-- hhmts start -->
Last modified: Wed Feb 10 15:31:34 CST 2010
<!-- hhmts end -->
</font>
</p>

</body>
</html>
